<div class="tmd-doc">
<h1 class="tmd-header-1">
Functions in Go
</h1>
<p></p>
<div class="tmd-usual">
<a href="function-declarations-and-calls.html">Function declarations and calls</a> have been explained before. The current article will touch more function related concepts and details in Go.
</div>
<p></p>
<p></p>
<div class="tmd-usual">
In fact, function is one kind of first-class citizen types in Go. In other words, we can use functions as values. Although Go is a static language, Go functions are very flexible. The feeling of using Go functions is much like using many dynamic languages.
</div>
<p></p>
<div class="tmd-usual">
There are some built-in functions in Go. These functions are documented in <a href="https://docs.go101.org/std/pkg/builtin.html"><code class="tmd-code-span">builtin</code></a> and <a href="https://docs.go101.org/std/pkg/unsafe.html"><code class="tmd-code-span">unsafe</code></a> standard code packages. Built-in functions have several differences from custom functions. These differences will be mentioned below.
</div>
<p></p>
<p></p>
<h3 class="tmd-header-3">
Function Signatures and Function Types
</h3>
<p></p>
<div class="tmd-usual">
The literal of a function type is composed of the <code class="tmd-code-span">func</code> keyword and a function signature literal. A function signature is composed of two type list, one is the input parameter type list, the other is the output result type lists. Parameter and result names can appear in function type and signature literals, but the names are not important.
</div>
<p></p>
<div class="tmd-usual">
In practice, the <code class="tmd-code-span">func</code> keyword can be presented in signature literals, or not. For this reason, we can think function type and function signature as the same concept.
</div>
<p></p>
<div class="tmd-usual">
Here is a literal of a function type:
</div>
<pre class="tmd-code disable-line-numbers111">
<code class="language-go">func (a int, b string, c string) (x int, y int, z bool)
</code></pre>
<p></p>
<div class="tmd-usual">
From the article <a href="function-declarations-and-calls.html">function declarations and calls</a>, we have learned that consecutive parameters and results of the same type can be declared together. So the above literal is equivalent to
</div>
<pre class="tmd-code disable-line-numbers111">
<code class="language-go">func (a int, b, c string) (x, y int, z bool)
</code></pre>
<p></p>
<div class="tmd-usual">
As parameter names and result names are not important in the literals (as long as there are no duplicate non-blank names), the above ones are equivalent to the following one.
</div>
<pre class="tmd-code disable-line-numbers111">
<code class="language-go">func (x int, y, z string) (a, b int, c bool)
</code></pre>
<p></p>
<div class="tmd-usual">
Variable (parameter and result) names can be blank identifier <code class="tmd-code-span">_</code>. The above ones are equivalent to the following one.
</div>
<pre class="tmd-code disable-line-numbers111">
<code class="language-go">func (_ int, _, _ string) (_, _ int, _ bool)
</code></pre>
<p></p>
<div class="tmd-usual">
The parameter names must be either all present or all absent (anonymous). The same rule is for result names. The above ones are equivalent to the following ones.
</div>
<pre class="tmd-code disable-line-numbers111">
<code class="language-go">func (int, string, string) (int, int, bool) // the standard form
func (a int, b string, c string) (int, int, bool)
func (x int, _ string, z string) (int, int, bool)
func (int, string, string) (x int, y int, z bool)
func (int, string, string) (a int, b int, _ bool)
</code></pre>
<p></p>
<div class="tmd-usual">
All of the above function type literals denote the same (unnamed) function type.
</div>
<p></p>
<div class="tmd-usual">
Each parameter list must be enclosed in a <code class="tmd-code-span">()</code> in a literal, even if the parameter list is blank. If a result list of a function type is blank, then it can be omitted from literal of the function type. When a result list has most one result, then the result list doesn't need to be enclosed in a <code class="tmd-code-span">()</code> if the literal of the result list contains no result names.
</div>
<p></p>
<pre class="tmd-code disable-line-numbers111">
<code class="language-go">// The following three function types are identical.
func () (x int)
func () (int)
func () int

// The following two function types are identical.
func (a int, b string) ()
func (a int, b string)
</code></pre>
<p></p>
<h4 id="variadic-parameter" class="tmd-header-4">
Variadic parameters and variadic function types
</h4>
<p></p>
<div class="tmd-usual">
The last parameter of a function can be a variadic parameter. Each function can have at most one variadic parameter. The type of a variadic parameter is always a slice type. To indicate the last parameter is variadic, just prefix three dots <code class="tmd-code-span">...</code> to the element type of its (slice) type in its declaration. Example:
</div>
<pre class="tmd-code disable-line-numbers111">
<code class="language-go">func (values ...int64) (sum int64)
func (sep string, tokens ...string) string
</code></pre>
<p></p>
<div class="tmd-usual">
A function type with variadic parameter can be called a variadic function type. A variadic function type and a non-variadic function type are absolutely not identical.
</div>
<p></p>
<div class="tmd-usual">
Some variadic functions examples will be shown in a below section.
</div>
<p></p>
<h4 class="tmd-header-4">
Function types are incomparable types
</h4>
<p></p>
<div class="tmd-usual">
It has been <a href="type-system-overview.html#types-not-support-comparison">mentioned</a> several times in Go 101 that function types are incomparable types. But like map and slice values, function values can compare with the untyped bare <code class="tmd-code-span">nil</code> identifier. (Function values will be explained in the last section of the current article.)
</div>
<p></p>
<p></p>
<div class="tmd-usual">
As function types are incomparable types, they can't be used as the key types of map types.
</div>
<p></p>
<h3 id="prototype" class="tmd-header-3">
Function Prototypes
</h3>
<p></p>
<div class="tmd-usual">
A function prototype is composed of a function name and a function type (or signature). Its literal is composed of the <code class="tmd-code-span">func</code> keyword, a function name and the literal of a function signature literal.
</div>
<p></p>
<div class="tmd-usual">
A function prototype literal example:
</div>
<pre class="tmd-code disable-line-numbers111">
<code class="language-go">func Double(n int) (result int)
</code></pre>
<p></p>
<div class="tmd-usual">
In other words, a function prototype is a function declaration without the body portion. A function declaration is composed of a function prototype and a function body.
</div>
<p></p>
<h3 id="variadic-function" class="tmd-header-3">
Variadic Function Declarations and Variadic Function Calls
</h3>
<p></p>
<div class="tmd-usual">
General function declarations and calls have been explained in <a href="function-declarations-and-calls.html">function declarations and calls</a>. Here introduces how to declare and call variadic functions.
</div>
<p></p>
<h4 class="tmd-header-4">
Variadic function declarations
</h4>
<p></p>
<div class="tmd-usual">
Variadic function declarations are similar to general function declarations. The difference is that the last parameter of a variadic function must be variadic parameter. Note, the variadic parameter of a variadic function will be treated as a slice within the body of the variadic function.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">// Sum and return the input numbers.
func Sum(values ...int64) (sum int64) {
	// The type of values is []int64.
	sum = 0
	for _, v := range values {
		sum += v
	}
	return
}

// An inefficient string concatenation function.
func Concat(sep string, tokens ...string) string {
	// The type of tokens is []string.
	r := ""
	for i, t := range tokens {
		if i != 0 {
			r += sep
		}
		r += t
	}
	return r
}
</code></pre>
<p></p>
<div class="tmd-usual">
From the above two variadic function declarations, we can find that if a variadic parameter is declared with type portion as <code class="tmd-code-span">...T</code>, then the type of the parameter is <code class="tmd-code-span">[]T</code> actually.
</div>
<p></p>
<div class="tmd-usual">
In fact, the <code class="tmd-code-span">Print</code>, <code class="tmd-code-span">Println</code> and <code class="tmd-code-span">Printf</code> functions in the <code class="tmd-code-span">fmt</code> standard package are all variadic functions.
</div>
<p></p>
<pre class="tmd-code line-numbers must-line-numbers">
<code class="language-go">func Print(a ...interface{}) (n int, err error)
func Printf(format string, a ...interface{}) (n int, err error)
func Println(a ...interface{}) (n int, err error)
</code></pre>
<p></p>
<div class="tmd-usual">
The variadic parameter types of the three functions are all <code class="tmd-code-span">[]interface{}</code>, which element type <code class="tmd-code-span">interface{}</code> is an interface types. Interface types and values will be explained <a href="interface.html">interfaces in Go</a> later.
</div>
<p></p>
<p></p>
<h4 id="variadic-call" class="tmd-header-4">
Variadic function calls
</h4>
<p></p>
<div class="tmd-usual">
There are two manners to pass arguments to a variadic parameter of type <code class="tmd-code-span">[]T</code>:
</div>
<ol class="tmd-list">
<li class="tmd-list-item">
<div class="tmd-usual">
pass a slice value as the only argument. The slice must be assignable to values of type <code class="tmd-code-span">[]T</code>, and the slice must be followed by three dots <code class="tmd-code-span">...</code>. The passed slice is called as a variadic argument.
</div>
</li>
<li class="tmd-list-item">
<div class="tmd-usual">
pass zero or more arguments which are assignable to values of type <code class="tmd-code-span">T</code>. These arguments will be copied (or converted) as the elements of a new allocated slice value of type <code class="tmd-code-span">[]T</code>, then the new allocated slice will be passed to the variadic parameter.
</div>
</li>
</ol>
<p></p>
<div class="tmd-usual">
Note, the two manners can't be mixed in the same variadic function call.
</div>
<p></p>
<div class="tmd-usual">
An example program which uses some variadic function calls:
</div>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

import "fmt"

func Sum(values ...int64) (sum int64) {
	sum = 0
	for _, v := range values {
		sum += v
	}
	return
}

func main() {
	a0 := Sum()
	a1 := Sum(2)
	a3 := Sum(2, 3, 5)
	// The above three lines are equivalent to
	// the following three respective lines.
	b0 := Sum([]int64{}...) // &lt;=&gt; Sum(nil...)
	b1 := Sum([]int64{2}...)
	b3 := Sum([]int64{2, 3, 5}...)
	fmt.Println(a0, a1, a3) // 0 2 10
	fmt.Println(b0, b1, b3) // 0 2 10
}
</code></pre>
<p></p>
<div class="tmd-usual">
Another example:
</div>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

import "fmt"

func Concat(sep string, tokens ...string) (r string) {
	for i, t := range tokens {
		if i != 0 {
			r += sep
		}
		r += t
	}
	return
}

func main() {
	tokens := []string{"Go", "C", "Rust"}
	// manner 1
	langsA := Concat(",", tokens...)
	// manner 2
	langsB := Concat(",", "Go", "C","Rust")
	fmt.Println(langsA == langsB) // true
}
</code></pre>
<p></p>
<div class="tmd-usual">
The following example doesn't compile, for the two variadic function call manners are mixed.
</div>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

// See above examples for the full declarations
// of the following two functions.
func Sum(values ...int64) (sum int64)
func Concat(sep string, tokens ...string) string

func main() {
	// The following two lines both fail
	// to compile, for the same error:
	// too many arguments in call.
	_ = Sum(2, []int64{3, 5}...)
	_ = Concat(",", "Go", []string{"C", "Rust"}...)
}
</code></pre>
<p></p>
<h3 class="tmd-header-3">
More About Function Declarations and Calls
</h3>
<p></p>
<h4 class="tmd-header-4">
Functions whose names can be duplicate
</h4>
<p></p>
<div class="tmd-usual">
Generally, the names of the functions declared in the same code package can't be duplicate. But there are two exceptions.
</div>
<ol class="tmd-list">
<li class="tmd-list-item">
<div class="tmd-usual">
One exception is each code package can declare several functions with <a href="packages-and-imports.html#init">the same name <code class="tmd-code-span">init</code> and the same type <code class="tmd-code-span">func ()</code></a>.
</div>
</li>
<li class="tmd-list-item">
<div class="tmd-usual">
The other exception is multiple functions can be declared with names as the blank identifier <code class="tmd-code-span">_</code>, in which cases, the declared functions can never be called.
</div>
</li>
</ol>
<p></p>
<p></p>
<h4 id="compile-time-evaluated-calls" class="tmd-header-4">
Some function calls are evaluated at compile time
</h4>
<p></p>
<div class="tmd-usual">
Most function calls are evaluated at run time. But calls to the functions of the <code class="tmd-code-span">unsafe</code> standard package are always evaluated at compile time. Calls to some other built-in functions, such as <code class="tmd-code-span">len</code> and <code class="tmd-code-span">cap</code>, <a href="summaries.html#compile-time-evaluation">may be evaluated at either compile time or run time</a>, depending on the passed arguments. The results of the function calls evaluated at compile time can be assigned to constants.
</div>
<p></p>
<p></p>
<h4 class="tmd-header-4">
All function arguments are passed by copy
</h4>
<p></p>
<div class="tmd-usual">
Let's repeat it again, like all value assignments in Go, all function arguments are passed by copy in Go. When a value is copied, <a href="value-part.html#about-value-copy">only its direct part is copied</a> (a.k.a., a shallow copy).
</div>
<p></p>
<p></p>
<h4 class="tmd-header-4">
Function declarations without bodies
</h4>
<p></p>
<div class="tmd-usual">
We can implement a function in <a href="https://golang.org/doc/asm">Go assembly</a>. Go assembly source files are stored in <code class="tmd-code-span">*.a</code> files. A function implemented in Go assembly is still needed to be declared in a <code class="tmd-code-span">*.go</code> file, but the only the prototype of the function is needed to be present. The body portion of the declaration of the function must be omitted in the <code class="tmd-code-span">*.go</code> file.
</div>
<p></p>
<p></p>
<h4 class="tmd-header-4">
Some functions with results are not required to return
</h4>
<p></p>
<div class="tmd-usual">
If a function has return results, then the last statement in its declaration body must be a <a href="https://golang.org/ref/spec#Terminating_statements">terminating statement</a>. Other than <code class="tmd-code-span">return</code> terminating statement, there are some other kinds of terminating statements. So a function body is not required to contain a return statement. For example,
</div>
<pre class="tmd-code line-numbers">
<code class="language-go">func fa() int {
	a:
	goto a
}

func fb() bool {
	for{}
}
</code></pre>
<p></p>
<p></p>
<h4 class="tmd-header-4">
The results of calls to custom function can be discarded, not true for calls to some built-in functions
</h4>
<p></p>
<div class="tmd-usual">
The return results of a custom function call can be all discarded together. However, the return results of calls to built-in functions, except <code class="tmd-code-span">recover</code> and <code class="tmd-code-span">copy</code>, can't be discarded, though they can be ignored by assigning them to some blank identifiers. Function calls whose results can't be discarded can't be used as deferred function calls or goroutine calls.
</div>
<p></p>
<h4 id="call-as-expression" class="tmd-header-4">
Use function calls as expressions
</h4>
<p></p>
<div class="tmd-usual">
A call to a function with single return result can always be used as a single value. For example, it can be nested in another function call as an argument, and can also be used as a single value to appear in any other expressions and statements.
</div>
<p></p>
<div class="tmd-usual">
If the return results of a call to a multi-result function are not discarded, then the call can only be used as a multi-value expression in two scenarios.
</div>
<ol class="tmd-list">
<li class="tmd-list-item">
<div class="tmd-usual">
The call can be used in an assignment as source values. But the call can't mix with other source values in the assignment.
</div>
</li>
<li class="tmd-list-item">
<div class="tmd-usual">
The call can be nested in another function call as arguments. But the call can't mix with other arguments.
</div>
</li>
</ol>
<p></p>
<div class="tmd-usual">
An example:
</div>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

func HalfAndNegative(n int) (int, int) {
	return n/2, -n
}

func AddSub(a, b int) (int, int) {
	return a+b, a-b
}

func Dummy(values ...int) {}

func main() {
	// These lines compile okay.
	AddSub(HalfAndNegative(6))
	AddSub(AddSub(AddSub(7, 5)))
	AddSub(AddSub(HalfAndNegative(6)))
	Dummy(HalfAndNegative(6))
	_, _ = AddSub(7, 5)

	// The following lines fail to compile.
	/*
	_, _, _ = 6, AddSub(7, 5)
	Dummy(AddSub(7, 5), 9)
	Dummy(AddSub(7, 5), HalfAndNegative(6))
	*/
}
</code></pre>
<p></p>
<div class="tmd-usual">
Note, for the standard Go compiler, <a href="exceptions.html#nest-function-calls">some built-in functions break the universality</a> of the just described rules above.
</div>
<p></p>
<p></p>
<h3 class="tmd-header-3">
Function Values
</h3>
<p></p>
<div class="tmd-usual">
As mentioned above, function types are one kind of types in Go. A value of a function type is called a function value. The zero values of function types are represented with the predeclared <code class="tmd-code-span">nil</code> identifier.
</div>
<p></p>
<div class="tmd-usual">
When we declare a custom function, we also declared an immutable function value actually. The function value is identified by the function name. The type of the function value is represented as the literal by omitting the function name from the function prototype literal.
</div>
<p></p>
<div class="tmd-usual">
Note, built-in functions can't be used as values. <code class="tmd-code-span">init</code> functions also can't be used as values.
</div>
<p></p>
<div class="tmd-usual">
Any function value can be invoked just like a declared function. It is fatal error to call a nil function to start a new goroutine. The fatal error is not recoverable and will make the whole program crash. For other situations, calls to nil function values will produce recoverable panics, including deferred function calls.
</div>
<p></p>
<div class="tmd-usual">
From the article <a href="value-part.html">value parts</a>, we know that non-nil function values are multi-part values. After one function value is assigned to another, the two functions share the same underlying parts(s). In other words, the two functions represent the same internal function object. The effects of invoking two functions are the same.
</div>
<p></p>
<p></p>
<div class="tmd-usual">
An example:
</div>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

import "fmt"

func Double(n int) int {
	return n + n
}

func Apply(n int, f func(int) int) int {
	return f(n) // the type of f is "func(int) int"
}

func main() {
	fmt.Printf("%T\n", Double) // func(int) int
	// Double = nil // error: Double is immutable.

	var f func(n int) int // default value is nil.
	f = Double
	g := Apply // let compile deduce the type of g
	fmt.Printf("%T\n", g) // func(int, func(int) int) int

	fmt.Println(f(9))         // 18
	fmt.Println(g(6, Double)) // 12
	fmt.Println(Apply(6, f))  // 12
}
</code></pre>
<p></p>
<div class="tmd-usual">
In the above example, <code class="tmd-code-span">g(6, Double)</code> and <code class="tmd-code-span">Apply(6, f)</code> are equivalent.
</div>
<p></p>
<div class="tmd-usual">
In practice, we often assign anonymous functions to function variables, so that we can call the anonymous functions multiple times.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

import "fmt"

func main() {
	// This function returns a function (a closure).
	isMultipleOfX := func (x int) func(int) bool {
		return func(n int) bool {
			return n%x == 0
		}
	}

	var isMultipleOf3 = isMultipleOfX(3)
	var isMultipleOf5 = isMultipleOfX(5)
	fmt.Println(isMultipleOf3(6))  // true
	fmt.Println(isMultipleOf3(8))  // false
	fmt.Println(isMultipleOf5(10)) // true
	fmt.Println(isMultipleOf5(12)) // false

	isMultipleOf15 := func(n int) bool {
		return isMultipleOf3(n) &amp;&amp; isMultipleOf5(n)
	}
	fmt.Println(isMultipleOf15(32)) // false
	fmt.Println(isMultipleOf15(60)) // true
}
</code></pre>
<p></p>
<div class="tmd-usual">
All functions in Go can be viewed as closures. This is one important reason why Go, as a static language, is flexible as many dynamic script languages.
</div>
<p></p>
<h3 id="range" class="tmd-header-3">
Range Over Functions (Since Go 1.23)
</h3>
<p></p>
<div class="tmd-usual">
Since Go 1.23, values of function types which underlying types are any of the following ones can be ranged over with <code class="tmd-code-span">for-range</code> loops.
</div>
<p></p>
<pre class="tmd-code disable-line-numbers111">
<code class="language-go">// K and V are some types.

func(yield func() bool)

func(yield func(V) bool)

func(yield func(K, V) bool)
</code></pre>
<p></p>
<div class="tmd-usual">
Such values are called push iterators, and often iterators in short.
</div>
<p></p>
<div class="tmd-usual">
When using a <code class="tmd-code-span">for-range</code> loop operates on such an iterator function value, the iterator function value will be called (once) with an implicitly constructed <code class="tmd-code-span">yield</code> callback function. The <code class="tmd-code-span">yield</code> callback function returns a <code class="tmd-code-span">bool</code> result. When it returns <code class="tmd-code-span">false</code>, the iterator function should not call the <code class="tmd-code-span">yield</code> function any more.
</div>
<p></p>
<div class="tmd-usual">
The following are some examples using such iterators.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

import "fmt"

func Loop3(yield func() bool) {
	if (!yield()) {
		return
	}
	if (!yield()) {
		return
	}
	yield()
}

func OneDigitNumbers(onValue func(int) bool) {
	for i := range 10 {
		if (!onValue(i)) {
			return
		}
	}
}

func SquareLessThan50(onKeyValue func(int, int) bool) {
	for i := range 8 {
		if (!onKeyValue(i, i*i)) {
			return
		}
	}
}

func main() {
	var n = 0
	for range Loop3 {
		fmt.Print(n)
		n++
	}
	fmt.Println()
	// Output: 012
	
	for i := range OneDigitNumbers {
		fmt.Print(i)
	}
	fmt.Println()
	// Output: 0123456789
	
	for i, ii := range SquareLessThan50 {
		fmt.Printf("%v:%v ", i, ii)
	}
	fmt.Println()
	// Output: 0:0 1:1 2:4 3:9 4:16 5:25 6:36 7:49 
}
</code></pre>
<p></p>
<div class="tmd-usual">
For the specified cases shown the above example, the <code class="tmd-code-span">for-range</code> loops are eqivalent to the following function calls, respectively.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">func main() {
	var n = 0
	Loop3(func() bool {
		fmt.Print(n)
		n++
		return true
	})
	fmt.Println()
	
	OneDigitNumbers(func(i int) bool {
		fmt.Print(i)
		return true
	})
	fmt.Println()
	
	SquareLessThan50(func(i, ii int) bool {
		fmt.Printf("%v:%v ", i, ii)
		return true
	})
	fmt.Println()
}
</code></pre>
<p></p>
<div class="tmd-usual">
However, please note that in some other cases, such equivalence may not hold.
</div>
<p></p>
<div class="tmd-usual">
Please read <a href="https://go.dev/blog/range-functions">this official blog article</a> and <a href="https://go101.org/blog/2025-03-15-some-facts-about-iterators.html">this article</a> for more about iterators in Go.
</div>
<p></p>
<p></p>
</div>
